#!/bin/ash

do_mount() {
    local mount_options="ro"

    [ ! -z "${2}" ] && mount_options="$mount_options,${2}"

    if mount -o $mount_options "${1}"           /boot_root; then return 0; fi
    return 1
}

do_root() {
    mkdir -p /boot_root /new_root /overlay_root /sys /proc || return 1
    mount -t proc  -o nodev,noexec,nosuid proc  /proc  	|| return 1
    mount -t sysfs -o nodev,noexec,nosuid sysfs /sys 	|| return 1
    mount -t devtmpfs none /dev

    # read the parameters
    read -r cmdline < /proc/cmdline

    # how many times to retry before moving on to the next dev/label/uuid
    devretry=5
    for param in ${cmdline} ; do
        case ${param} in
            devretry=*) devretry=${param#devretry=};;
        esac
    done

    MOUNTARG=none
    boot_root_mounted=n
    MOUNTOPTIONS=none
    while [ $boot_root_mounted = n ]
    do
        for param in ${cmdline}
        do
            MOUNTOPTIONS=${param#*:} # gets everything after the first colon :
            param=${param%%:*} # gets everything before the first colon :
            [ "$MOUNTOPTIONS" == "$param" ] && MOUNTOPTIONS= #in case there is no colon :, set MOUNTOPTIONS to nothing

            case ${param} in
                dev=*)      MOUNTARG=${param#dev=};;
                label=*)    MOUNTARG=LABEL=${param#label=};;
                uuid=*)     MOUNTARG=UUID=${param#uuid=};;
                *)          continue;;
            esac
            for i in $(seq $devretry)
            do
                if do_mount "${MOUNTARG}" "${MOUNTOPTIONS}"
                then
                    echo "Mounted ${MOUNTARG} as /boot_root"
                    boot_root_mounted=y
                    break
                fi
                echo "Waiting for the root device ${MOUNTARG}"
                sleep 1
            done
            if [ $boot_root_mounted = y ]
            then
                break
            fi
        done
    done

    # update the squashfs
    if test -e /boot_root/boot/batocera.update
    then
      mount -o remount,rw /boot_root || return 1
      mv /boot_root/boot/batocera.update /boot_root/boot/batocera || return 1
      # remove the overlay when updating
      if test -e /boot_root/boot/overlay
      then
	  mv /boot_root/boot/overlay /boot_root/boot/overlay.old      || return 1
      fi
      mount -o remount,ro /boot_root || return 1
    fi

    # create an overlay on memory
    mount -t tmpfs -o size=256M tmpfs /overlay_root || return 1
    mkdir /overlay_root/base /overlay_root/overlay /overlay_root/work /overlay_root/saved || return 1

    # fill the overlay with the stored one
    if test -f /boot_root/boot/overlay
    then
	# the mount can fail if the fs was open in write and not correctly closed
	if mount -o ro /boot_root/boot/overlay /overlay_root/saved
	then
	    cp -pr /overlay_root/saved/* /overlay_root/overlay || return 1
	    umount /overlay_root/saved                         || return 1
	fi
    fi

    # mount the squashfs
    mount /boot_root/boot/batocera /overlay_root/base || return 1

    # mount the future root in read write
    if ! mount -t overlay overlay -o rw,lowerdir=/overlay_root/base,upperdir=/overlay_root/overlay,workdir=/overlay_root/work /new_root
    then
	# mount only as squashfs, no overlay (xu4 doesn't support overlayfs)
	mount /boot_root/boot/batocera /new_root || return 1
    fi

    # moving current mounts
    mount --move /boot_root    /new_root/boot    || return 1
    mount --move /overlay_root /new_root/overlay || return 1
    mount --move /sys  	       /new_root/sys  	 || return 1
    mount --move /proc 	       /new_root/proc 	 || return 1
    mount --move /dev  	       /new_root/dev  	 || return 1

    # switch to the new root
    exec switch_root /new_root /sbin/init || return 1
}

if ! do_root
then
    echo "oooutch !"
    /bin/ash
fi
